package com.cash.channel.svc.service.common;

import com.cash.channel.svc.logic.ChannelLogic;
import com.cash.channel.svc.logic.ProductLogic;
import com.cash.channel.svc.logic.ThirdCommonLogic;
import com.cash.channel.svc.model.ChannelInfo;
import com.cash.channel.svc.service.base.LoanSubmit;
import com.alibaba.fastjson.JSON;
import com.cash.channel.api.constant.Constant;
import com.cash.channel.api.model.ApiRequestModel;
import com.cash.channel.api.model.ApiResponseModel;
import com.cash.channel.api.model.request.LoanSubmitRequest;
import com.cash.channel.api.model.response.LoanSubmitResponse;
import com.cash.channel.api.model.user.ThirdIdModel;
import com.cash.channel.api.model.user.ThirdUserIdModel;
import com.cash.channel.svc.dao.ApplyWithdrawalFlowMapper;
import com.cash.channel.svc.model.ApplyWithdrawalFlow;
import com.cash.cms.model.DictModel;
import com.cash.cms.service.CashConfigService;
import com.cash.user.model.FaceVerifyFlowModel;
import com.cash.user.model.UserChannelCardPackModel;
import com.cash.user.model.UserInfoResultModel;
import com.cash.user.service.UserChannelService;
import com.cash.user.service.UserService;
import com.geex.haneda.HanedaException;
import com.geex.haneda.model.api.ApiReqModel;
import com.geex.haneda.model.api.ApiResModel;
import com.geex.haneda.service.ApiService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import geex.core.service.ProductService;
import geex.core.service.model.emuns.ProductTypeEnum;
import geex.core.service.model.product.Product;
import geex.core.service.model.product.ProductServiceCharge;
import geex.core.service.model.product.SearchProductRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author  zhuweiqiang
 */
@Slf4j
@Service(Constant.CHANNEL.COMMON+ Constant.SERVICE.提现申请)
public class CommonLoanSubmit implements LoanSubmit {

    @Autowired
    private ThirdCommonLogic thirdCommonLogic;

    @Autowired
    private ProductService productService;

    @Autowired
    private ProductLogic productLogic;

    @Autowired
    private UserService userService;

    @Autowired
    private ChannelLogic channelLogic;

    @Autowired
    private UserChannelService userChannelService;

    @Autowired(required = false)
    private ApiService hanedaApiService;

    @Autowired
    private ApplyWithdrawalFlowMapper applyWithdrawalFlowMapper;

    @Override
    public ApiResponseModel<LoanSubmitResponse> doLoanSubmit(ApiRequestModel apiRequestModel) {
        LoanSubmitRequest loanSubmitRequest = JSON.parseObject(apiRequestModel.getData(), LoanSubmitRequest.class);
        try {
            String faceFlowId =loanSubmitRequest.getFaceFlowId();
            Integer loanTerm =loanSubmitRequest.getPeriod();
            BigDecimal loanAmount =loanSubmitRequest.getLoanAmt();
            String channel =apiRequestModel.getChannel();
            channelLogic.checkChannelQuota(channel, loanAmount);
            ThirdUserIdModel thirdUserInfo = thirdCommonLogic.getThirdUserInfo(loanSubmitRequest.getOrderNo(), channel);
            UserInfoResultModel userInfoModel = thirdUserInfo.getUserInfoModel();
            ThirdIdModel thirdInfo = thirdUserInfo.getThirdIdModel();

            Boolean flag= thirdCommonLogic.checkOrderStatus(userInfoModel.getcUid(),loanAmount);
            if(!flag){
                return new ApiResponseModel<>(false,0,"审批提现前置条件不符合",null);
            }
            Product product = productLogic.findProductById(loanSubmitRequest.getPeriod(), null, channel);

            if (null == product) {
                return new ApiResponseModel<>(false,0,"未查询到对应产品",null);
            }
            if(loanAmount.compareTo(new BigDecimal(1000))<0){
                return new ApiResponseModel<>(false,0,"请选择大于1000的提现金额",null);
            }
            if(loanAmount.intValue()%100!=0){
                return new ApiResponseModel<>(false,0,"请选择为100倍数的提现金额",null);
            }
            FaceVerifyFlowModel faceVerifyFlowModel = userService.getFaceResultByFlowId(faceFlowId);
            log.info("人脸识别结果" + faceVerifyFlowModel);
            if (null == faceVerifyFlowModel||!thirdInfo.getCUserUid().equals(faceVerifyFlowModel.getCUuid())) {
                return new ApiResponseModel<>(false,0,"未查询到对应人脸识别结果",null);
            }
            if(StringUtils.isBlank(thirdInfo.getCWdId())||!thirdInfo.getCWdId().equals(faceVerifyFlowModel.getCWdId())){
                return new ApiResponseModel<>(false,0,"未查询到对应订单号",null);
            }

            UserChannelCardPackModel userChannelCardPackModel = this.userChannelService.findUserChannelDefaultCard(userInfoModel.getcUid(), channel);
            log.info("用户提现银行卡结果" + userChannelCardPackModel);
            if (null == userChannelCardPackModel) {
                return new ApiResponseModel<>(false,0,"未查询到用户提现银行卡",null);
            }
            Map<String, Object> orderInfoMap = createOrderInfoMap(thirdInfo.getCAppId(), thirdInfo.getCWdId(), faceVerifyFlowModel, userInfoModel, product, loanAmount.toString(), "54",
                    userChannelCardPackModel.getcCardNo(), userChannelCardPackModel.getcBankCode(), userChannelCardPackModel.getcReserveMobile(), faceVerifyFlowModel.getCSourceImg(), faceVerifyFlowModel.getCImg1(), faceVerifyFlowModel.getCImg2(), faceVerifyFlowModel.getCImg3());
            updWDOrderBAAPI(orderInfoMap);
            //保存提现流水
            ApplyWithdrawalFlow applyWithdrawalFlow = new ApplyWithdrawalFlow();
            applyWithdrawalFlow.setcWdId(thirdInfo.getCWdId());
            applyWithdrawalFlow.setcThirdId(thirdInfo.getCThirdId());
            applyWithdrawalFlow.setcChannel(thirdInfo.getCChannel());
            applyWithdrawalFlow.setnLoanAmount(loanAmount);
            applyWithdrawalFlow.setnLoanTerm(loanTerm);
            applyWithdrawalFlow.setcBankCard(userChannelCardPackModel.getcCardNo());
            applyWithdrawalFlow.setcBankMobile(userChannelCardPackModel.getcReserveMobile());
            applyWithdrawalFlow.setcBankCode(userChannelCardPackModel.getcBankCode());
            applyWithdrawalFlow.setdCreate(new Date());

            applyWithdrawalFlowMapper.insert(applyWithdrawalFlow);

            LoanSubmitResponse loanSubmitResponse =new LoanSubmitResponse();
            loanSubmitResponse.setWithdrawId(thirdInfo.getCWdId());

            return new ApiResponseModel<>(true, 0, "", loanSubmitResponse);
        }catch (Exception e){
            log.error("通过订单号:{}获取产品信息异常:{}",loanSubmitRequest.getOrderNo(), e.getMessage(),e);
            return new ApiResponseModel<>(false,0,"获取产品信息异常",null);
        }
    }

    private Map<String, Object> createOrderInfoMap(String appId, String wdId, FaceVerifyFlowModel faceVerifyFlowModel, UserInfoResultModel userInfo,
                                                          Product productInfo, String nWdAmt, String cCapitalUse,
                                                          String cRpMethod, String cBankCode, String cBankMobile,
                                                          String... imageUrl) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("cQcAppId", appId);
        params.put("cWDAppId", wdId);
        params.put("cUuid", userInfo.getcUid());
        params.put("cName", userInfo.getcName());
        params.put("cIdno", userInfo.getcIdno());
        params.put("cWdProduct", productInfo.getProductCode());
        params.put("nWdAmt", nWdAmt);
        // 弃用
        params.put("nMemberServiceFlag", -1);
        params.put("cCapitalUse", cCapitalUse);
        params.put("nWdPeriod", productInfo.getTenor());
        params.put("cRpMethod", cRpMethod);
        params.put("cBankCode", cBankCode);
        params.put("cBankMobile", cBankMobile);
        params.put("nUserPercent", productInfo.getPercentUser());
        params.put("face", createFaceResult(faceVerifyFlowModel, imageUrl));
        params.put("product", createWDProductMap(productInfo));
        return params;
    }

    private List<Map<String, Object>> createFaceResult(FaceVerifyFlowModel faceVerifyFlowModel, String[] imageUrl) {
        List<Map<String, Object>> faceParams = Lists.newArrayList();
        Map<String, Object> param = null;
        String url = null;
        for (int i = 0; i < imageUrl.length; i++) {
            url = imageUrl[i];
            if (StringUtils.isEmpty(url)) {
                continue;
            }
            param = Maps.newHashMap();
            param.put("cStorePath", url);
            param.put("cStoreName", url.substring(url.lastIndexOf("/") + 1));
            param.put("nType", 3333);
            if (i == 0) {
                createParamWithVerify(param, faceVerifyFlowModel);
                param.put("nType", 3202);
            }
            faceParams.add(param);
        }
        return faceParams;
    }

    private void createParamWithVerify(Map<String, Object> param, FaceVerifyFlowModel faceVerifyFlowModel) {
        param.put("cConfidence", faceVerifyFlowModel.getCConfidence());
        param.put("c1e3", faceVerifyFlowModel.getC1e6());
        param.put("c1e4", faceVerifyFlowModel.getC1e6());
        param.put("c1e5", faceVerifyFlowModel.getC1e6());
        param.put("c1e6", faceVerifyFlowModel.getC1e6());
        param.put("cContent", faceVerifyFlowModel.getCResponseContent());
    }

    private List<Map<String, Object>> createWDProductMap(Product productInfo) {
        List<Map<String, Object>> productMapList = Lists.newArrayList();
        Map<String, Object> productMap = null;
        if (productInfo.getProductServiceChargeList() != null) {
            for (ProductServiceCharge productServiceCharge : productInfo.getProductServiceChargeList()) {
                productMap = Maps.newHashMap();
                productMap.put("nPeriod", productServiceCharge.getTenor());
                productMap.put("cRate", productServiceCharge.getPercentCharge());
                productMapList.add(productMap);
            }
        }
        return productMapList;
    }

    private Map<String, Object> updWDOrderBAAPI(Map<String, Object> params) throws HanedaException {
        try {
            log.info("风控端：保存提现订单:" + params);
            com.alibaba.fastjson.JSONObject requestObj = new com.alibaba.fastjson.JSONObject();
            requestObj.putAll(params);
            ApiResModel apiResModel = hanedaApiService.api(new ApiReqModel("updWDOrderBAAPI", requestObj.toString()));
            if (!apiResModel.getSuccess()) {
                log.error("风控端：保存提现订单失败:" + params + "\t" + apiResModel.getErrMessage());
                throw new HanedaException(apiResModel.getErrMessage());
            }

            log.info("风控端：保存提现订单:" + params);
            return null;
        } catch (Exception ex) {
            log.error("风控端：保存提现订单失败:" + params + "\t" + ex.getMessage(), ex);
            throw ex;
        }
    }

}
